package presentation;

import businessEntities.BEFileUtils;
import businessEntities.FilesConfig;
import businessEntities.QueryResultContainer;
import businessLogic.BLConnetionManager;
import businessLogic.BLFileImporter;
import java.io.File;
import presentation.entities.JFrameWrapper;
import java.awt.Toolkit;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import presentation.entities.DialogCreator;
import presentation.entities.QueryTableModel;

public class ConnectionScreen extends javax.swing.JFrame {

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        connection_panel = new javax.swing.JPanel();
        port_textField = new javax.swing.JTextField();
        connect_button = new javax.swing.JButton();
        password_label = new javax.swing.JLabel();
        hostAdrres_label = new javax.swing.JLabel();
        password_textField = new javax.swing.JPasswordField();
        userName_textField = new javax.swing.JTextField();
        host_textField = new javax.swing.JTextField();
        userName_label = new javax.swing.JLabel();
        port_label = new javax.swing.JLabel();
        userErr_label = new javax.swing.JLabel();
        passwordErr_label = new javax.swing.JLabel();
        portErr_label = new javax.swing.JLabel();
        hostErr_label = new javax.swing.JLabel();
        mainError_label = new javax.swing.JLabel();
        icon_label = new javax.swing.JLabel();
        title_label = new javax.swing.JLabel();
        menuBar = new javax.swing.JMenuBar();
        navigation_menu = new javax.swing.JMenu();
        close_menuItem = new javax.swing.JMenuItem();
        tools_menu = new javax.swing.JMenu();
        csvImport_menuItem = new javax.swing.JMenuItem();
        xmlIport_menuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Connect to MySQL Host");
        setBackground(new java.awt.Color(185, 209, 234));
        setIconImage(Toolkit.getDefaultToolkit().getImage(PresentationConfig.framesIconPath));
        setLocationByPlatform(true);
        setName("connectionScreen_frame"); // NOI18N
        setResizable(false);

        connection_panel.setPreferredSize(new java.awt.Dimension(500, 300));

        port_textField.setFont(new java.awt.Font("Microsoft YaHei", 0, 15));
        port_textField.setText("3306");

        connect_button.setFont(new java.awt.Font("Microsoft YaHei", 1, 18));
        connect_button.setText("Connect");
        connect_button.setIconTextGap(10);
        connect_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                connect_buttonActionPerformed(evt);
            }
        });

        password_label.setFont(new java.awt.Font("Microsoft YaHei", 1, 18));
        password_label.setText("Password");

        hostAdrres_label.setFont(new java.awt.Font("Microsoft YaHei", 1, 18));
        hostAdrres_label.setText("Host Address");
        hostAdrres_label.setToolTipText("Server's hostname or IP address");

        password_textField.setFont(new java.awt.Font("Microsoft YaHei", 1, 15));

        userName_textField.setFont(new java.awt.Font("Microsoft YaHei", 0, 15));

        host_textField.setFont(new java.awt.Font("Microsoft YaHei", 0, 15));

        userName_label.setFont(new java.awt.Font("Microsoft YaHei", 1, 18));
        userName_label.setText("User Name");
        userName_label.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

        port_label.setFont(new java.awt.Font("Microsoft YaHei", 1, 18));
        port_label.setText("Port");
        port_label.setToolTipText("Port number. MySQL Server default port is 3306");
        port_label.setFocusable(false);
        port_label.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

        userErr_label.setFont(new java.awt.Font("Tahoma", 1, 11));
        userErr_label.setForeground(new java.awt.Color(255, 0, 0));

        passwordErr_label.setFont(new java.awt.Font("Tahoma", 1, 11));
        passwordErr_label.setForeground(new java.awt.Color(255, 0, 0));

        portErr_label.setFont(new java.awt.Font("Tahoma", 1, 11));
        portErr_label.setForeground(new java.awt.Color(255, 0, 0));

        hostErr_label.setFont(new java.awt.Font("Tahoma", 1, 11));
        hostErr_label.setForeground(new java.awt.Color(255, 0, 0));

        mainError_label.setFont(new java.awt.Font("Tahoma", 1, 12));
        mainError_label.setForeground(new java.awt.Color(255, 0, 0));

        icon_label.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/database_mysql.png"))); // NOI18N

        javax.swing.GroupLayout connection_panelLayout = new javax.swing.GroupLayout(connection_panel);
        connection_panel.setLayout(connection_panelLayout);
        connection_panelLayout.setHorizontalGroup(
            connection_panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, connection_panelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(connection_panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(icon_label, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(userName_label, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)
                    .addComponent(password_label, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)
                    .addComponent(hostAdrres_label, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(connection_panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(mainError_label, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE)
                    .addComponent(userName_textField, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE)
                    .addComponent(hostErr_label, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE)
                    .addComponent(host_textField, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE)
                    .addComponent(password_textField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE)
                    .addComponent(passwordErr_label, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE)
                    .addComponent(userErr_label, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE)
                    .addGroup(connection_panelLayout.createSequentialGroup()
                        .addComponent(port_label)
                        .addGap(18, 18, 18)
                        .addComponent(port_textField, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(portErr_label, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE)
                    .addComponent(connect_button, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE))
                .addContainerGap())
        );
        connection_panelLayout.setVerticalGroup(
            connection_panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, connection_panelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(connection_panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(hostAdrres_label, javax.swing.GroupLayout.DEFAULT_SIZE, 26, Short.MAX_VALUE)
                    .addComponent(host_textField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(hostErr_label, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(connection_panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(userName_textField)
                    .addComponent(userName_label, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(userErr_label, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(connection_panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(password_label, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(password_textField))
                .addGroup(connection_panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(connection_panelLayout.createSequentialGroup()
                        .addGap(14, 14, 14)
                        .addComponent(passwordErr_label, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(connection_panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(port_label)
                            .addComponent(port_textField))
                        .addGap(5, 5, 5)
                        .addComponent(portErr_label, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(connect_button)
                        .addGap(11, 11, 11)
                        .addComponent(mainError_label, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(connection_panelLayout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(icon_label, javax.swing.GroupLayout.DEFAULT_SIZE, 161, Short.MAX_VALUE)))
                .addContainerGap())
        );

        title_label.setFont(new java.awt.Font("Arial Rounded MT Bold", 1, 20));
        title_label.setForeground(new java.awt.Color(0, 0, 255));
        title_label.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        title_label.setText("Connect to MySQL Host");
        title_label.setPreferredSize(new java.awt.Dimension(34, 24));

        menuBar.setMaximumSize(new java.awt.Dimension(75, 32769));

        navigation_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/navigation-icon.png"))); // NOI18N
        navigation_menu.setText("Navigation");
        navigation_menu.setFont(new java.awt.Font("Arial Rounded MT Bold", 1, 12));

        close_menuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.SHIFT_MASK));
        close_menuItem.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12));
        close_menuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/shutdown-icon.png"))); // NOI18N
        close_menuItem.setText("Close");
        close_menuItem.setToolTipText("Close the program");
        close_menuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                close_menuItemActionPerformed(evt);
            }
        });
        navigation_menu.add(close_menuItem);

        menuBar.add(navigation_menu);

        tools_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/tools-icon.png"))); // NOI18N
        tools_menu.setText("Tools");
        tools_menu.setFont(new java.awt.Font("Arial Rounded MT Bold", 1, 12));

        csvImport_menuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.event.InputEvent.SHIFT_MASK));
        csvImport_menuItem.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12)); // NOI18N
        csvImport_menuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/excel-icon.png"))); // NOI18N
        csvImport_menuItem.setText("Import Query Result from CSV");
        csvImport_menuItem.setToolTipText("Import query result from CSV file");
        csvImport_menuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                csvImport_menuItemActionPerformed(evt);
            }
        });
        tools_menu.add(csvImport_menuItem);

        xmlIport_menuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.SHIFT_MASK));
        xmlIport_menuItem.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12)); // NOI18N
        xmlIport_menuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/xml_icon.png"))); // NOI18N
        xmlIport_menuItem.setText("Import Query Result from XML");
        xmlIport_menuItem.setToolTipText("Import query result from XML file");
        xmlIport_menuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                xmlIport_menuItemActionPerformed(evt);
            }
        });
        tools_menu.add(xmlIport_menuItem);

        menuBar.add(tools_menu);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(connection_panel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 424, Short.MAX_VALUE)
                    .addComponent(title_label, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 424, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(title_label, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(connection_panel, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void connect_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_connect_buttonActionPerformed
    clearErrorLabels();
    
    String host = this.host_textField.getText();
    String userName = this.userName_textField.getText();
    String port = this.port_textField.getText();
    String password = new String(password_textField.getPassword());
    boolean fieldsValidated = isValidInput(host,userName,port);
  
    //Checks wether the input parameters legal
    if(fieldsValidated)
    {
       BLConnetionManager conMenager = new BLConnetionManager();
       boolean connctionAvailible = conMenager.initializeConnection(host,userName,password,port);
       
       if(connctionAvailible){
            ListsScreen nextScreen = new ListsScreen();
            JFrameWrapper wrapper = new JFrameWrapper(nextScreen);
            setVisible(false);
            javax.swing.SwingUtilities.invokeLater(wrapper);
            this.dispose();         
       }
       else{
            mainError_label.setText("* Could not connect to the server.");
       }
     }
}//GEN-LAST:event_connect_buttonActionPerformed

private void close_menuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_close_menuItemActionPerformed
    setVisible(false);
    this.dispose();
}//GEN-LAST:event_close_menuItemActionPerformed

    private void csvImport_menuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_csvImport_menuItemActionPerformed
        
        File workspaceDir = new File(FilesConfig.WORKSPACE_DIR_PATH);
        JFileChooser fileChooser;
        if(workspaceDir.isDirectory()){
            fileChooser = new JFileChooser(workspaceDir);
        }
        else {
            fileChooser = new JFileChooser(System.getProperty("user.home"));
        }    
            
        fileChooser.setFileFilter(new FileFilter() {

            @Override
            public boolean accept(File f) {
                if(f.isDirectory()) return true;
                if(BEFileUtils.getFileExtention(f.getPath()).equals("csv")) return true;
                return false;
            }

            @Override
            public String getDescription() {
                return ".csv";
            }
        });
       
       int returnVal = fileChooser.showOpenDialog(this);
       if(returnVal == JFileChooser.APPROVE_OPTION) {
           File file = fileChooser.getSelectedFile();
           BLFileImporter importer = new BLFileImporter();
           QueryResultContainer dataContainer = importer.importFromCSV(file);
           if(dataContainer == null){
               String errorMessage =  "Could not read data from the given file."
                                    + "\nFor more information please refer 'runtime.log'";
               DialogCreator.showMessage(this,"Import Error",errorMessage,JOptionPane.WARNING_MESSAGE );
           }
           else {
               QueryTableModel model = new QueryTableModel(dataContainer);
               TableFrame frame = new TableFrame("Imported from " + file, model);
               JFrameWrapper wrapper = new JFrameWrapper(frame);
               javax.swing.SwingUtilities.invokeLater(wrapper);
           }
       }
    }//GEN-LAST:event_csvImport_menuItemActionPerformed

    private void xmlIport_menuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_xmlIport_menuItemActionPerformed
        
        File workspaceDir = new File(FilesConfig.WORKSPACE_DIR_PATH);
        JFileChooser fileChooser;
        if(workspaceDir.isDirectory()){
            fileChooser = new JFileChooser(workspaceDir);
        }
        else {
            fileChooser = new JFileChooser(System.getProperty("user.home"));
        }
       
       fileChooser.setFileFilter(new FileFilter() {

            @Override
            public boolean accept(File f) {
                if(f.isDirectory()) return true;
                if(BEFileUtils.getFileExtention(f.getPath()).equals("xml")) return true;
                return false;
            }

            @Override
            public String getDescription() {
                return ".xml";
            }
        });
       
       int returnVal = fileChooser.showOpenDialog(this);
       if(returnVal == JFileChooser.APPROVE_OPTION) {
           File file = fileChooser.getSelectedFile();
           BLFileImporter importer = new BLFileImporter();
           QueryResultContainer dataContainer = importer.importFromXML(file);
           if(dataContainer == null){
               String errorMessage =  "Could not read data from the given file."
                                    + "\nFor more information please refer 'runtime.log'";
               DialogCreator.showMessage(this,"Import Error",errorMessage,JOptionPane.WARNING_MESSAGE );
           }
           else {
               QueryTableModel model = new QueryTableModel(dataContainer);
               TableFrame frame = new TableFrame("Imported from " + file, model);
               JFrameWrapper wrapper = new JFrameWrapper(frame);
               javax.swing.SwingUtilities.invokeLater(wrapper);
           }
       }                              
    }//GEN-LAST:event_xmlIport_menuItemActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem close_menuItem;
    private javax.swing.JButton connect_button;
    private javax.swing.JPanel connection_panel;
    private javax.swing.JMenuItem csvImport_menuItem;
    private javax.swing.JLabel hostAdrres_label;
    private javax.swing.JLabel hostErr_label;
    private javax.swing.JTextField host_textField;
    private javax.swing.JLabel icon_label;
    private javax.swing.JLabel mainError_label;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenu navigation_menu;
    private javax.swing.JLabel passwordErr_label;
    private javax.swing.JLabel password_label;
    private javax.swing.JPasswordField password_textField;
    private javax.swing.JLabel portErr_label;
    private javax.swing.JLabel port_label;
    private javax.swing.JTextField port_textField;
    private javax.swing.JLabel title_label;
    private javax.swing.JMenu tools_menu;
    private javax.swing.JLabel userErr_label;
    private javax.swing.JLabel userName_label;
    private javax.swing.JTextField userName_textField;
    private javax.swing.JMenuItem xmlIport_menuItem;
    // End of variables declaration//GEN-END:variables

    /** Creates new form ConnectionScreen **/
    public ConnectionScreen() {
        initComponents();

        // sets the frame location to the center of the screen
        setLocationRelativeTo(null);

        //Sets connect_button to be the default button of the frame (react to Enter).
        this.getRootPane().setDefaultButton(connect_button);

        host_textField.requestFocusInWindow();

    }

    /** 
     *  Returns true if there is no problems with the input parameters the user entered.
     **/
    private boolean isValidInput(String host, String userName, String port) {
        boolean result = true;

        //validate port
        try {
            int intPort = Integer.parseInt(port);
            if (intPort < 0 || intPort > 65535) {
                portErr_label.setText("* Port is an integer between 0 to 65535");
                result = false;
                port_textField.setText("");
            }
        } catch (NumberFormatException e) {
            portErr_label.setText("* Port is an integer between 0 to 65535");
            result = false;
            port_textField.setText("");
        }

        //validate user name
        if (userName.equals("")) {
            userErr_label.setText("* User Name is required");
            result = false;
            userName_textField.setText("");
        }

        //validate host
        if (host.equals("")) {
            hostErr_label.setText("* Hostname or IP address is required");
            result = false;
            host_textField.setText("");
        }

        return result;
    }

    private void clearErrorLabels() {
        portErr_label.setText("");
        hostErr_label.setText("");
        userErr_label.setText("");
        mainError_label.setText("");
    }
}
